package org.infoset.xml;

import java.util.*;
import java.net.*;


/**
 * This interface represents an XML element.
 * @author <a href="mailto:alex@milowski.com">R. Alexander Milowski</a>
 */
public interface Element extends Parent,Child,Named,Prefixed,Location,Validity {

   boolean hasAttributes();

   /**
    * Returns a map of the attribute names to attribute items.  A put() on
    * this map of an attribute owned by another element will create a copy
    * of the attribute.  As such, a get() is required to get the actual
    * attribute item.  A put() of an attribute created via the Document 
    * interface will not create a copy.
    */
   Map<Name,Attribute> getAttributes();
   
   /**
    * Gets an attribute by an unqualified name.  This is the same as
    * getAttributes().get(Name.create(local));
    * @param local The unqualified name of the attribute.
    * @return An attribute instance or null if the attribute does not exist.
    */
   //Attribute getAttribute(String local);

   /**
    * Gets an attribute value by name.  If the attribute does not exist, a null
    * value is returned.
    * @param name The name of the attribute.
    * @return The string value of the attribute or null.
    */
   String getAttributeValue(Name name);

   /**
    * Gets an attribute value by an unqualified name.  This is the same as
    * getAttributeValue(Name.create(local));
    * @param local The unqualified name of the attribute.
    * @return A data value for the attribute or null if the attribute does not exist.
    */
   String getAttributeValue(String local);


   /**
    * Gets an attribute value by name.
    * @param name The name of the attribute.
    * @return A data value for the attribute or null if the attribute does not exist.
    */
   //Iterator getAttributeValueTokenized(Name name);

   /**
    * Gets an attribute value by an unqualified name.
    * @param local The unqualified name of the attribute.
    * @return A data value for the attribute or null if the attribute does not exist.
    */
   //Iterator getAttributeValueTokenized(String local);

   /**
    * Sets an attribute value by name.  If the attribute does not exist, it will be create.
    * @param name The name of the attribute.
    * @param value The data value to use.
    */
   Attribute setAttributeValue(Name name,String value);

   /**
    * Sets an attribute value by name.  If the attribute does not exist, it will be create.
    * This is the is the same as setAttribute(Name.create(localName),value);
    * @param localName The unqualified name of the attribute.
    * @param value The data value to use.
    */
   Attribute setAttributeValue(String localName,String value);

   /**
    * Removes an attribute by an unqualified name.  This is the same as
    * getAttributes().remove(Name.create(local));
    * @param local The unqualfied name of the attribute.
    */
   //void removeAttribute(String local);

   /**
    * Appends a new element to the end of the children content.
    * @param name The name of the element to create.
    * @return An instance of element with the specified name.
    */
   Element addElement(Name name);

   /**
    * Appends a new element to the end of the children content.
    * @param local The local name to be interpreted by the namespace scope of the element to create.
    * @return An instance of element with the specified name.
    */
   Element addElement(String local);

   /**
    * Inserts a new element to the end of the children content.
    * @param index The index of the position of where to create the element where zero is the beginning of the children content.
    * @param name The name of the element to create.
    * @return An instance of element with the specified name.
    */
   Element addElement(int index,Name name);

   /**
    * Inserts a new element into the children content.
    * @param index The index of the position of where to create the element where zero is the beginning of the children content.
    * @param local The local name to be interpreted by the namespace scope of the element to create.
    * @return An instance of element with the specified name.
    */
   Element addElement(int index,String local);

   /**
    * Appends a data object to the end of the children content.
    * @param data The data object to append.
    * @return An instance of Child that conforms to Data as well.
    */
   Characters addData(Object data);

   /**
    * Appends a data object to the end of the children content.
    * @param data The data object to append.
    * @return An instance of Child that conforms to Data as well.
    */
   Characters addCharacters(String data);

   /**
    * Inserts a data object into the children content.
    * @param index The index of the position of where to create the data child where zero is the beginning of the children content.
    * @param data The data object to append.
    * @return An instance of Data.
    */
   Child addData(int index,Object data);
   
   /**
    * Inserts a data object into the children content.
    * @param index The index of the position of where to create the data child where zero is the beginning of the children content.
    * @param value The data object to append.
    * @return An instance of Data.
    */
   Child addCharacters(int index,String value);
   
   /**
    * Indicates if the element is set to preserve space.
    */
   boolean isSpacePreserving();

   /**
    * Sets the default namespace locally.
    * @param namespace The namespace name to be set as default.
    */
   void addNamespaceBinding(String prefix,URI namespace);

   /**
    * Returns the namespace scope associated with this element.
    */
   NamespaceScope getNamespaceScope();

   /**
    * Signals that the namespace scope is local to this node and not the 
    * parent's namespace scope.
    * @return Returns true if namespace scope is local to this node.
    */
   boolean hasNamespaceDeclarations();
   
   /**
    * Localizes all namespace declarations.  This is useful when mixing element item streams.
    */
   
   void localizeNamespaceDeclarations();

   Iterator getInScopeNamespaces();

   String getText();
   String getNormalizedText();
   
   Iterator<Element> getElementsByName(Name name);
   Element getFirstElementNamed(Name name);
   Iterator<Element> getElementChildren();
   
}
